<html>
<head>

<!-- https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css -->
<style type="text/css">
			
	@charset"UTF-8";

	/* CSS Document */
	 html, body {
	    margin: 0;
	    padding: 0;
	    font-family:'Open Sans', sans-serif;
	    color: #494949;
	}
	#wrapper {
	    width: 300px;
	    margin: 0 auto;
	}
	.callInfo {
	    width: 190px;
	    height: 70px;
	    float: left;
	}
	#connectedCall .callInfo {
	    width: 240px;
	}
	#dialPad div{
	    -moz-user-select: -moz-none;
	    -khtml-user-select: none;
	    -webkit-user-select: none;
	    
	    /*
	    Introduced in IE 10.
	    See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/
	    */
	    -ms-user-select: none;
	    user-select: none;
	}
	.callInfo h3 {
	    color: #389400;
	    margin: 10px 0 10px 0;
	}
	.callInfo p {
	    margin: 0px 25px 0px 0px;
	    float: left;
	}
	#answer, #hangUp, #reject, #connectCall, #mute {
	    color: #FFF;
	    background-color: #389400;
	    width: 50px;
	    height: 50px;
	    float: right;
	    text-align: center;
	    font-size: 30px;
	    margin: 10px 0px 10px 0px;
	    border-radius: 25px 25px 25px 25px;
	    -moz-border-radius: 25px 25px 25px 25px;
	    -webkit-border-radius: 25px 25px 25px 25px;
	    cursor: pointer;
	    cursor: hand;
	}
	#mute:active, #connectCall:active, #reject:active, #hangUp:active, #answer:active {
	    background-color: #B6B6B6;
	    -webkit-box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    -moz-box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    border: none;
	}
	#hangUp, #reject {
	    -ms-transform: rotate(135deg);
	    /* IE 9 */
	    -webkit-transform: rotate(135deg);
	    /* Chrome, Safari, Opera */
	    transform: rotate(135deg);
	}
	#hangUp {
	    background-color: #A90002;
	}
	#reject {
	    background-color: #FFF;
	    color: #A90002;
	    margin-right: 10px;
	}
	#connectCall, #mute {
	    color: #FFF;
	    background-color: #389400;
	    width:260px;
	    height: 50px;
	    font-size: 30px;
	    text-align: center;
	    margin: 20px 20px 0px 20px;
	    border-radius: 5px 5px 5px 5px;
	    -moz-border-radius: 5px 5px 5px 5px;
	    -webkit-border-radius: 5px 5px 5px 5px;
	    cursor: pointer;
	    cursor: hand;
	}
	#mute {
	    color: #545454;
	    margin: 0 auto;
	    width: 50px;
	    height: 50px;
	    margin: 15px 125px 10px 20px;
	    border-radius: 25px 25px 25px 25px;
	    -moz-border-radius: 25px 25px 25px 25px;
	    -webkit-border-radius: 25px 25px 25px 25px;
	    background-color: #FFF;
	}
	.muteActive {
	    color: #FFF;
	    background-color:#389400;
	}
	#to {
	    border-bottom: 2px solid #BBBBBB;
	}
	#toField {
	    margin-top: 20px;
	    padding-left: 10px;
	    font-size: 1em;
	    font-family:'Open Sans', sans-serif;
	    width: 300px;
	    height: 40px;
	    border-radius: 2px 2px 2px 2px;
	    -moz-border-radius: 2px 2px 2px 2px;
	    -webkit-border-radius: 2px 2px 2px 2px;
	    border: 0px solid #B8B8B8;
	}
	#dialPad {
	    width: 240px;
	    height: 308px;
	    margin:0 auto;
	}
	#dialPad div {
	    float: left;
	    width: 50px;
	    height: 50px;
	    text-align: center;
	    font-size: 26px;
	    margin: 25px 15px 0px 15px;
	    box-sizing:border-box;
	    -moz-box-sizing:border-box;
	    -webkit-box-sizing:border-box;
	    border-radius: 25px 25px 25px 25px;
	    -moz-border-radius: 25px 25px 25px 25px;
	    -webkit-border-radius: 25px 25px 25px 25px;
	    border: 1px solid #E8E8E8;
	    padding-top: 5px;
	}
	#dialPad div:hover {
	    background-color: #389400;
	    color: #FFF;
	    cursor: pointer;
	    cursor: hand;
	}
	#dialPad div:active {
	    background-color: #B2B2B2;
	    -webkit-box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    -moz-box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    box-shadow: 0px 1px 7px 2px rgba(0, 0, 0, 0.45);
	    border: none;
	}
	.fa {
	    margin-top: 11px;
	}
	#answer .fa {
	    -webkit-animation: callp 1s;
	    animation: callp 1s;
	    -webkit-animation-iteration-count: infinite;
	    -webkit-animation-direction: alternate;
	    -webkit-animation-play-state: running;
	    animation-iteration-count: infinite;
	    animation-direction: alternate;
	    animation-play-state: running;
	}
	@-webkit-keyframes callp {
	    from {
	        color: #FFF;
	    }
	    to {
	        color: #389400;
	    }
	}
	@keyframes callp {
	    from {
	        color: #FFF;
	    }
	    to {
	        color: #389400;
	    }
	}
	#answer {
	    -webkit-animation: call 1s;
	    animation: call 1s;
	    -webkit-animation-iteration-count: infinite;
	    -webkit-animation-direction: alternate;
	    -webkit-animation-play-state: running;
	    animation-iteration-count: infinite;
	    animation-direction: alternate;
	    animation-play-state: running;
	}
	@-webkit-keyframes call {
	    from {
	        background: #389400;
	    }
	    to {
	        background: #FFF;
	    }
	}
	@keyframes call {
	    from {
	        background: #389400;
	    }
	    to {
	        background: #FFF;
	    }
	}
</style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jssip/3.1.2/jssip.min.js"></script>

</head>

<body>

<div id="errorMessage">must set sip uri/password</div>
<div id="wrapper">
    <div id="incomingCall" style="display: none">
        <div class="callInfo">
            <h3>Incoming Call</h3>
            <p id="incomingCallNumber">Unknown</p>
        </div>
        <div id="answer"> <i class="fa fa-phone"></i></div>
        <div id="reject"> <i class="fa fa-phone"></i></div>
    </div>
    <div id="callStatus" style="display: none">
        <div class="callInfo">
             <h3 id="callInfoText">info text goes here</h3>
            <p id="callInfoNumber">info number goes here</p>
        </div>
        <div id="hangUp"> <i class="fa fa-phone"></i>
        </div>
    </div>
    <!---------TO FIELD---------------------------------------------------->
    <!---------DIALPAD---------------------------------------------------->
    <div id="inCallButtons" style="display: none">
        <div id="dialPad">
            
            <div class="dialpad-char" data-value="1" unselectable="on">1</div>
            <div class="dialpad-char" data-value="2" unselectable="on">2</div>
            <div class="dialpad-char" data-value="3" unselectable="on">3</div>
            <div class="dialpad-char" data-value="4" unselectable="on">4</div>
            <div class="dialpad-char" data-value="5" unselectable="on">5</div>
            <div class="dialpad-char" data-value="6" unselectable="on">6</div>
            <div class="dialpad-char" data-value="7" unselectable="on">7</div>
            <div class="dialpad-char" data-value="8" unselectable="on">8</div>
            <div class="dialpad-char" data-value="9" unselectable="on">9</div>
            <div class="dialpad-char" data-value="*" unselectable="on">*</div>
            <div class="dialpad-char" data-value="0" unselectable="on">0</div>
            <div class="dialpad-char" data-value="#" unselectable="on">#</div>
        </div>
        <div id="mute">
            <i id="muteIcon" class="fa fa-microphone"></i>
        </div>
    </div>

<!---------DIAL CONTROLS-------------------------------------------->
<div id="callControl">
    <div id="to">
        <input id="toField" type="text" placeholder="Enter number here"/>
    </div>
    <div id="connectCall"> <i class="fa fa-phone"></i>

    </div>
</div>
</div>


<script>
var socket = new JsSIP.WebSocketInterface('wss://34.201.19.107:443');
var configuration = {
  sockets  : socket,
  uri      : 'sip:alice@34.201.19.107',
  password : 'superpassword'
};

var incomingCallAudio = new window.Audio('https://code.bandwidth.com/media/incoming_alert.mp3');
incomingCallAudio.loop = true;
var remoteAudio = new window.Audio();
remoteAudio.autoplay = true;

var callOptions = {
  mediaConstraints: {audio: true, video: false}
};

var phone;
if(configuration.uri && configuration.password){
    
    JsSIP.debug.enable('JsSIP:*'); // more detailed debug output
    
    phone = new JsSIP.UA(configuration);
    
    phone.on('registrationFailed', function(ev){
    	alert('Registering on SIP server failed with error: ' + ev.cause);
      	configuration.uri = null;
      	configuration.password = null;
      	updateUI();
    });

    phone.on('newRTCSession',function(ev){
        var newSession = ev.session;
        if(session){ 
        	// hangup any existing call
            session.terminate();
        }
        session = newSession;
        var completeSession = function(){
        	session = null;
          	updateUI();
        };
        session.on('ended', completeSession);
        session.on('failed', completeSession);
        session.on('accepted',updateUI);
        session.on('confirmed',function(){
        	var localStream = session.connection.getLocalStreams()[0];
          	var dtmfSender = session.connection.createDTMFSender(localStream.getAudioTracks()[0])
          	session.sendDTMF = function(tone){
            	dtmfSender.insertDTMF(tone);
          	};
          	updateUI();
        });
        session.on('addstream', function(e){
          	//incomingCallAudio.pause();
          	remoteAudio.src = window.URL.createObjectURL(e.stream);
          	console.log("addstream " , remoteAudio.src);
        });

        if(session.direction === 'incoming'){
        	incomingCallAudio.play();
        }
        updateUI();
    });
    phone.start();
}

var session;
updateUI();

$('#connectCall').click(function () {
    var dest = $('#toField').val();
    phone.call(dest, callOptions);
    updateUI();
});

$('#answer').click(function(){
    session.answer(callOptions);
});

var hangup = function(){
	session.terminate();
};

$('#hangUp').click(hangup);
$('#reject').click(hangup);

$('#mute').click(function(){
    if(session.isMuted().audio){
        session.unmute({audio: true});
    }else{
        session.mute({audio: true});   
    }
    updateUI();
});

$('#toField').keypress(function(e){
    if(e.which === 13){//enter
        $('#connectCall').click();
    }
});

$('#inCallButtons').on('click', '.dialpad-char', function (e) {
    var $target = $(e.target);
    var value = $target.data('value');
    session.sendDTMF(value.toString());
});

function updateUI(){
    if(configuration.uri && configuration.password){
        $('#errorMessage').hide();
        $('#wrapper').show();
        if(session){
            if(session.isInProgress()){
            	console.log("session.isInProgress");
                if(session.direction === 'incoming'){
                    $('#incomingCallNumber').html(session.remote_identity.uri);
                    $('#incomingCall').show();
                    $('#callControl').hide()  
                    $('#incomingCall').show();
                }else{
                    $('#callInfoText').html('Ringing...');
                    $('#callInfoNumber').html(session.remote_identity.uri.user);
                    $('#callStatus').show();                   
                }
                
            }else if(session.isEstablished()){
            	console.log("session.isEstablished");
                $('#callStatus').show();
                $('#incomingCall').hide();
                $('#callInfoText').html('In Call');
                $('#callInfoNumber').html(session.remote_identity.uri.user);
                $('#inCallButtons').show();
                //incomingCallAudio.pause();
            }
            $('#callControl').hide();
        }else{
        	console.warn("no session");
            $('#incomingCall').hide();
            $('#callControl').show();
            $('#callStatus').hide();
            $('#inCallButtons').hide();
            incomingCallAudio.pause();
        }
        //microphone mute icon
        if(session && session.isMuted().audio){
            $('#muteIcon').addClass('fa-microphone-slash');
            $('#muteIcon').removeClass('fa-microphone');
        }else{
            $('#muteIcon').removeClass('fa-microphone-slash');
            $('#muteIcon').addClass('fa-microphone');
        }
    }else{
        $('#wrapper').hide();
        $('#errorMessage').show();
    }
}

</script>

</body>
</html>